﻿using System;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Identity;
using JwtWebApi.Filters;
using JwtWebApi.Models;
using JwtWebApi.Models.ViewModel;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;

namespace JwtWebApi.Controllers
{
    [Authorize]
    [ApiController]
    [Route("[controller]")]
    [EnableCors]
    public class AccountController : ControllerBase
    {
        private readonly AppSettings _appSettings;
        private readonly SignInManager<User> _userService;
        private readonly UserManager<User> userManager;

        public AccountController(SignInManager<User> userService,
            IOptions<AppSettings> appSettings, UserManager<User> userManager)
        {
            _userService = userService;
            this.userManager = userManager;

            _appSettings = appSettings.Value;
        }

        [AllowAnonymous]
        [HttpPost("Login")]
        public async Task<IActionResult> LoginAsync([FromBody] LoginViewModel model)
        {
            var result =
                await _userService.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, false);
            if (result.Succeeded)
            {
                var tokenHandler = new JwtSecurityTokenHandler();
                var key = Encoding.UTF8.GetBytes(_appSettings.Secret);

                var user = _userService.UserManager.Users.First(f => f.NormalizedUserName == model.UserName);
                var tokenDescriptor = new SecurityTokenDescriptor
                {
                    Expires = DateTime.UtcNow.AddDays(7),
                    SigningCredentials =
                        new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256)
                };
                tokenDescriptor.Subject = new ClaimsIdentity(new[]
                {
                    new Claim(ClaimTypes.Name, user.UserName),
                    //new Claim(ClaimTypes.Email, user.Email??"noexist@jkjk.com"),
                    new Claim(ClaimTypes.NameIdentifier, user.Id)
                });
                var token = tokenHandler.CreateToken(tokenDescriptor);


                return Ok(
                    new
                    {
                        token = tokenHandler.WriteToken(token),
                        success = true
                    });
            }

            var message = "账号或密码出错";
            if (result.IsLockedOut) message = "账号尝试次数过多，暂时被禁用";

            if (result.IsNotAllowed) message = "账号已经永久被禁用";

            return Ok(
                new
                {
                    message,
                    success = false
                });
        }

        [HttpGet("info")]
        public async Task<IActionResult> Info()
        {
            var name = User.Identity.Name;
            var user = await userManager.FindByNameAsync(name)
                ;

            return Ok(new
            {
                User.Identity.Name,
                user.UserName,
                user.NormalizedUserName,
                roles = _userService.UserManager.GetRolesAsync(user).Result
            });
        }

        [HttpPost("ChangePassword")]
        [ModelValidteFilter]
        public IActionResult ChangePassword([FromBody]ChangePasswordModel model)
        {
            var user = userManager.GetUserAsync(this.User);
            var r = userManager.ChangePasswordAsync(user.Result, model.Password, model.NewPassword).Result;
            return Ok(new
            {
                successed = r.Succeeded,
                message = string.Join(',', r.Errors.Select(f => f.Description))
            });
        }
        [HttpPost("logout")]
        public IActionResult Logout()
        {
            return Ok("ok");
        }
    }
}